package com.system.core.utils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DecimalFormat;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class TinyMoney implements Serializable, Comparable<Object>{

	private static final long serialVersionUID = 7630205931836901846L;

	public static final int DEFAULT_ROUNDING_MODE = 6;

    /**小数位数*/
    public static final int DEFAULT_DIGITS = 6;

    private long microYuan;


    public TinyMoney(BigDecimal amount) {
        this.microYuan = this.rounding(amount.movePointRight(DEFAULT_DIGITS), DEFAULT_ROUNDING_MODE);
    }

    public TinyMoney(Money money){
        this(money.getAmount());
    }

    /**
     * 按元初始化
     * @param amount
     */
    public TinyMoney(String amount){
        this(new BigDecimal(amount == null ? "" : amount));
    }

    public TinyMoney(){
        this.microYuan =0L;
    }

    public static TinyMoney cent(BigDecimal cent){
        BigDecimal val = cent.movePointRight(DEFAULT_DIGITS - 2);
        val.setScale(0,DEFAULT_ROUNDING_MODE);
        TinyMoney money = new TinyMoney();
        money.setMicroYuan(val.longValue());
        return money;
    }

    public static TinyMoney microYuan(long microYuan){
        TinyMoney money = new TinyMoney();
        money.setMicroYuan(microYuan);
        return money;
    }


    public BigDecimal getCent(){
      return    BigDecimal.valueOf(this.microYuan).movePointLeft(DEFAULT_DIGITS-2);
    }


    protected long rounding(BigDecimal val, int roundingMode) {
        return val.setScale(0, roundingMode).longValue();
    }

    public TinyMoney add(TinyMoney other){
        return newMoney(this.microYuan +other.microYuan);
    }

    public TinyMoney addTo(TinyMoney other){
        this.microYuan +=other.microYuan;
        return this;
    }

    public TinyMoney divide(double val){

        return  newMoney(Math.round(this.microYuan / val));
    }

    public TinyMoney subtract(TinyMoney other){
        return newMoney(this.microYuan -other.microYuan);
    }

    public TinyMoney subtractFrom(TinyMoney other){
        this.microYuan -= other.microYuan;
        return this;
    }

    public static TinyMoney zero(){
        return new TinyMoney();
    }

    public TinyMoney multiply(BigDecimal val){
        BigDecimal newVal = BigDecimal.valueOf(this.microYuan).multiply(val);
        return newMoney(this.rounding(newVal,DEFAULT_ROUNDING_MODE));
    }

    public TinyMoney multiply(double val){
        return  newMoney(Math.round(this.microYuan * val));
    }

    public TinyMoney multiply(long val){
        return  newMoney(this.microYuan *val);
    }

    protected TinyMoney newMoney(long number){
        TinyMoney money = new TinyMoney();
        money.setMicroYuan(number);
        return money;
    }

    public BigDecimal getAmount() {
        return BigDecimal.valueOf(this.microYuan,DEFAULT_DIGITS );
    }

    /**
     * 转换成money
     * @return
     */
    public Money toMoney(){
        return new Money(this.getAmount());
    }

    public int compareTo(TinyMoney other) {
        if (this.microYuan < other.microYuan) {
            return -1;
        } else {
            return this.microYuan == other.microYuan ? 0 : 1;
        }
    }

    @Override
	public int compareTo(Object other) {
        return this.compareTo((TinyMoney)other);
    }



    public long getMicroYuan() {
        return microYuan;
    }

    public void setMicroYuan(long microYuan) {
        this.microYuan = microYuan;
    }

    @Override
	public String toString() {
        return this.getAmount().toString();
    }

    public String getStandardString(){
        return toStandardString();
    }

    public String toStandardString() {
        DecimalFormat fmt = new DecimalFormat("##,###,###,###,###.00####");
        String result = fmt.format(this.getAmount().doubleValue());
        if (result.indexOf(".") == 0) {
            result = "0" + result;
        }
        return result;
    }
}
